package de.uni.muenster.idw2;

import java.util.ArrayList;
import java.util.LinkedList;

import org.osmdroid.DefaultResourceProxyImpl;
import org.osmdroid.ResourceProxy;
import org.osmdroid.util.BoundingBoxE6;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.ItemizedIconOverlay.OnItemGestureListener;
import org.osmdroid.views.overlay.MyLocationOverlay;
import org.osmdroid.views.overlay.OverlayItem;

import com.google.android.maps.MapActivity;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;


import de.uni.muenster.idw2.data.BBBuilding;
import de.uni.muenster.idw2.data.BoundingBox;
import de.uni.muenster.idw2.dialogs.BuildingDialog;
import de.uni.muenster.idw2.threads.BBBuildingLoaderThread;


public class BuildingChooserMap extends MapActivity{
	
	public static final int MAP_ACTIVITY_RESULT = 1337;
	public static final String MAP_ACTIVITY_RESULT_DATA = "buildingInformation";
	
	private MapView mapView;
	private MapController mapController;
	private MyLocationOverlay myLocationOverlay;
	private ItemizedIconOverlay<OverlayItem> overlayBuildingItems;
	private LinkedList<OverlayItem> overLayList;
	private LinkedList<BBBuilding> buildings = new LinkedList<BBBuilding>();
	private ProgressBar progressBar;
	private BBBuildingLoaderThread bbBuildingLoaderThread = null;
	
	private boolean openDialog = false;

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.building_map);
		
		progressBar = (ProgressBar) findViewById(R.id.title_refresh_progress);
		
		initMap();
	}
	
	/**
	 * setup the map
	 */
	private void initMap(){
		mapView = (MapView) findViewById(R.id.mapview);
		mapController = mapView.getController();
		
		mapController.setZoom(10);
		mapView.setClickable(true);
		mapView.setMultiTouchControls(true);
		mapView.setBuiltInZoomControls(true);
		
		
		myLocationOverlay = new MyLocationOverlay(this, mapView);
		myLocationOverlay.enableCompass();
		myLocationOverlay.enableMyLocation();
		
		mapView.getOverlays().add(myLocationOverlay);
		
		if(myLocationOverlay.getMyLocation() != null){
			GeoPoint gp = myLocationOverlay.getMyLocation();
			mapController.animateTo(gp);
			mapController.setZoom(10);
			loadBB(gp, true);
		}
		else{
			GeoPoint gp = new GeoPoint(51.9, 7.6); // muenster
			mapController.animateTo(gp);
			loadBB(gp, true);
		}
		
		
		/**
		 * create overlay items
		 */
		ResourceProxy mResourceProxy = new DefaultResourceProxyImpl(this);
		
		overLayList = new LinkedList<OverlayItem>();
		
		OnItemGestureListener<OverlayItem> itemClickListener = new OnItemGestureListener<OverlayItem>() {
			@Override
			public boolean onItemLongPress(int arg0, OverlayItem arg1) {
				return false;
			}

			@Override
			public boolean onItemSingleTapUp(final int pos, OverlayItem arg1) {
				
				if(!openDialog){
					openDialog = true;
					BuildingDialog buildingDialog = new BuildingDialog(BuildingChooserMap.this, buildings.get(pos), BuildingChooserMap.this);
					buildingDialog.show();
				}
				
				return false;
			}
			
		};
		
		Drawable icon = getResources().getDrawable(R.drawable.marker_house);
		
		overlayBuildingItems = new ItemizedIconOverlay<OverlayItem>(overLayList, icon, itemClickListener, mResourceProxy);
		
		mapView.getOverlays().add(overlayBuildingItems);
		
		mapView.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				loadBB(null, false);
			}
		});
	}
	
	public void showProgress(){
		progressBar.setVisibility(View.VISIBLE);
	}
	
	public void hideProgress(){
		progressBar.setVisibility(View.GONE);
	}
	
	public void addOverlayBuildings(BoundingBox boundingBox){
		ArrayList<BBBuilding> buildings = boundingBox.getBuildings();
		for (BBBuilding b : buildings) {
			
			String name = b.getName();
			String path = b.getPath();
			double lat = b.getLat();
			double lon = b.getLon();
			
			OverlayItem item = new OverlayItem(name, path, new GeoPoint(lat, lon));
			
			//if the geopoint or the is not the same, the item will be added
			boolean isEqual = false;
			for(int i = 0; i < overlayBuildingItems.size(); i++){
				OverlayItem a = overlayBuildingItems.getItem(i);
				if(item.mDescription.equals(a.mDescription)){
					isEqual = true;
				}
			}
			if(!isEqual){
				overlayBuildingItems.addItem(item);
				this.buildings.add(b);
			}
		}
	}
	
	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
	
	private void loadBB(GeoPoint midpoint, boolean useGeopoint){
		
		double lat_top_right;
		double lat_bottom_left;
		double lon_top_right;
		double lon_bottom_left;
		
		if(!useGeopoint){
			BoundingBoxE6 bbdsaf = mapView.getProjection().getBoundingBox();
			
			lat_top_right = ((double)bbdsaf.getLatNorthE6()) / 1E6;
			lat_bottom_left = ((double)bbdsaf.getLatSouthE6()) / 1E6;
			lon_top_right = ((double)bbdsaf.getLonEastE6()) / 1E6;
			lon_bottom_left = ((double)bbdsaf.getLonWestE6()) / 1E6;
		}
		else{
			lat_top_right = ((double)midpoint.getLatitudeE6()+ 300000) / 1E6;
			lat_bottom_left = ((double)midpoint.getLatitudeE6()- 300000) / 1E6;
			lon_top_right = ((double)midpoint.getLongitudeE6()+ 300000) / 1E6;
			lon_bottom_left = ((double)midpoint.getLongitudeE6()- 300000) / 1E6;
		}
		
		BoundingBox bbRequest = new BoundingBox(lon_bottom_left, lon_top_right, lat_bottom_left, lat_top_right);
		 
		if (bbBuildingLoaderThread != null && !bbBuildingLoaderThread.isCancelled()) {
			bbBuildingLoaderThread.cancel(true);
		}
		
		bbBuildingLoaderThread  = new BBBuildingLoaderThread(this, bbRequest);
		bbBuildingLoaderThread.execute();
		
	}
	
	
    public void onRefreshClick(View view){
    	if(myLocationOverlay.getMyLocation() != null){
			GeoPoint gp = myLocationOverlay.getMyLocation();
			mapController.setZoom(12);
			mapController.animateTo(gp);
			loadBB(gp, true);
		}
    }
    
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
    	super.onWindowFocusChanged(hasFocus);
    }
    
    
    
    @Override
    protected void onStop() {
    	super.onStop();
    	
    	myLocationOverlay.disableCompass();
    	myLocationOverlay.disableMyLocation();
    }
    
    @Override
    protected void onPause() {
    	this.finish();
    	super.onPause();
    }

	public void setOpenDialog(boolean openDialog) {
		this.openDialog = openDialog;
	}

	public boolean isOpenDialog() {
		return openDialog;
	}
	
}
